﻿namespace FlexField.Metadata
{
    /// <summary>
    /// Provides an abstraction for a storage and management of metadata types.
    /// </summary>
    public interface IEntityStore<TKey> : IDisposable where TKey : IEquatable<TKey>
    {
        /// <summary>
        /// Creates a new metadata entity in a store as an asynchronous operation.
        /// </summary>
        /// <param name="entity">The metadata entity to create in the store.</param>
        /// <param name="cancellationToken">The <see cref="CancellationToken"/> used to propagate notifications that the operation should be canceled.</param>
        /// <returns>A <see cref="Task{TResult}"/> that represents the <see cref="MetadataResult"/> of the asynchronous query.</returns>
        Task<MetadataResult> CreateAsync(MetadataEntity<TKey> entity, CancellationToken cancellationToken);

        /// <summary>
        /// Updates a metadata entity in a store as an asynchronous operation.
        /// </summary>
        /// <param name="entity">The metadata entity to update in the store.</param>
        /// <param name="cancellationToken">The <see cref="CancellationToken"/> used to propagate notifications that the operation should be canceled.</param>
        /// <returns>A <see cref="Task{TResult}"/> that represents the <see cref="MetadataResult"/> of the asynchronous query.</returns>
        Task<MetadataResult> UpdateAsync(MetadataEntity<TKey> entity, CancellationToken cancellationToken);

        /// <summary>
        /// Deletes a metadata entity from the store as an asynchronous operation.
        /// </summary>
        /// <param name="entity">The metadata entity to delete from the store.</param>
        /// <param name="cancellationToken">The <see cref="CancellationToken"/> used to propagate notifications that the operation should be canceled.</param>
        /// <returns>A <see cref="Task{TResult}"/> that represents the <see cref="MetadataResult"/> of the asynchronous query.</returns>
        Task<MetadataResult> DeleteAsync(MetadataEntity<TKey> entity, CancellationToken cancellationToken);

        /// <summary>
        /// Finds the metadata entity who has the specified ID as an asynchronous operation.
        /// </summary>
        /// <param name="entityId">The entity ID to look for.</param>
        /// <param name="cancellationToken">The <see cref="CancellationToken"/> used to propagate notifications that the operation should be canceled.</param>
        /// <returns>A <see cref="Task{TResult}"/> that result of the look up.</returns>
        Task<MetadataEntity<TKey>> FindByIdAsync(TKey entityId, CancellationToken cancellationToken);

        /// <summary>
        /// Finds the metadata entity who has the specified name as an asynchronous operation.
        /// </summary>
        /// <param name="entityName">The entity name to look for.</param>
        /// <param name="cancellationToken">The <see cref="CancellationToken"/> used to propagate notifications that the operation should be canceled.</param>
        /// <returns>A <see cref="Task{TResult}"/> that result of the look up.</returns>
        Task<MetadataEntity<TKey>> FindByNameAsync(string entityName, CancellationToken cancellationToken);

        /// <summary>
        /// Gets a list of all the metadata entities.
        /// </summary>
        /// <param name="cancellationToken">The <see cref="CancellationToken"/> used to propagate notifications that the operation should be canceled.</param>
        /// <returns>A <see cref="Task{TResult}"/> that represents the result of the asynchronous query, a list of <see cref="MetadataEntity{TKey}"/>.</returns>
        Task<IList<MetadataEntity<TKey>>> GetAllAsync(CancellationToken cancellationToken);

        /// <summary>
        /// Returns a list of metadata entities associated with the specified property name and property value.
        /// </summary>
        /// <param name="propertyName">The name of the entity property.</param>
        /// <param name="propertyValue">The value of the entity property.</param>
        /// <param name="cancellationToken">The <see cref="CancellationToken"/> used to propagate notifications that the operation should be canceled.</param>
        /// <returns>A <see cref="Task{TResult}"/> that represents the result of the asynchronous query, a list of <see cref="MetadataEntity{TKey}"/>s who contain the specified property.</returns>
        Task<IList<MetadataEntity<TKey>>> FindByPropertyAsync(string propertyName, string propertyValue, CancellationToken cancellationToken);
    }
}
